#include "stdafx.h"
#include "AreaUtils.h"

#include "ExclusionST2.h"
#include "InclusionDlg.h"
#include "LayoutUtils.h"
#include <bitset>
#include "Const.h"

using namespace nsLayoutUtils;
//using namespace nsAreaUtils;
using namespace nsExclusionStatic2;
using namespace std;

void nsAreaUtils::setAreasToArrayFromDevmod(
	OUT SEXCLUSIONAREAS ArrayDst[], 
	IN const SPEC_AREA *pAreaSrc, 
	IN const size_t nAreasMax )
{
	size_t i, iSide;
	SEXCLUSION Exclusion;

	ArrayDst[ esFront ].vExclusionList.clear();
	ArrayDst[ esBack ].vExclusionList.clear();

	for ( i = 0; i < nAreasMax; i++ )
	{
		if ( ( pAreaSrc->side == AREA_FRONT || pAreaSrc->side == AREA_BACK ) &&
			 ( pAreaSrc->left & pAreaSrc->top & pAreaSrc->right & pAreaSrc->bottom ) != ULONG_MAX )
		{
			iSide = pAreaSrc->side == AREA_FRONT ? esFront : esBack;

			Exclusion.bActive = pAreaSrc->fEnable == TRUE ? true : false;
			Exclusion.Area.Rect.left = pAreaSrc->left;
			Exclusion.Area.Rect.top = pAreaSrc->top;
			Exclusion.Area.Rect.right = pAreaSrc->right;
			Exclusion.Area.Rect.bottom = pAreaSrc->bottom;
			Exclusion.Area.nOffsetX = pAreaSrc->nOffsetX;
			Exclusion.Area.nOffsetY = pAreaSrc->nOffsetY;

			ArrayDst[ iSide ].vExclusionList.push_back( Exclusion );
		}
		++pAreaSrc;
	}

	ArrayDst[ esFront ].iCurrentExclusion = -1;
	ArrayDst[ esBack ].iCurrentExclusion = -1;
}

void nsAreaUtils::getAreasFromArray( OUT std::vector<SPEC_AREA> &vAreaDst, 
	IN const nsExclusionStatic2::ESIDE Side, 
	IN const nsExclusionStatic2::SEXCLUSIONAREAS &ArraySrc )
{
/*
	SEXCLUSIONAREAS Areas;
	
	pPic->GetExclusionAreasTo( &Areas );
*/
	SPEC_AREA AreaTemp;
	AreaTemp.side = Side == esFront ? AREA_FRONT : AREA_BACK;

	vector<SEXCLUSION>::const_iterator start = ArraySrc.vExclusionList.begin(),
		end = ArraySrc.vExclusionList.end();

	while ( start != end )
	{
		AreaTemp.fEnable = start->bActive;
		AreaTemp.left = start->Area.Rect.left;
		AreaTemp.top = start->Area.Rect.top;
		AreaTemp.right = start->Area.Rect.right;
		AreaTemp.bottom = start->Area.Rect.bottom;
		AreaTemp.nOffsetX = start->Area.nOffsetX;
		AreaTemp.nOffsetY = start->Area.nOffsetY;

		vAreaDst.push_back( AreaTemp );

		++start;
	}
}


void nsAreaUtils::setAreasToDevmod( OUT SPEC_AREA *pAreaDst, 
	IN const vector<SPEC_AREA> &vAreaSrc, 
	IN const int nAreasMax )
{
	int iPos = 0;
	vector<SPEC_AREA>::const_iterator start = vAreaSrc.begin(),
		end = vAreaSrc.end();


	while ( start != end && iPos < nAreasMax )
	{
		*pAreaDst++ = *start++;
		iPos++;
	}

	// check if we have to fill the rest
	if ( iPos < nAreasMax )
	{
		SPEC_AREA DummyArea;
		DummyArea.fEnable = FALSE;
		DummyArea.left =
		DummyArea.top =
		DummyArea.right =
		DummyArea.bottom =
		DummyArea.plane =
		DummyArea.side = ULONG_MAX;
		DummyArea.nOffsetX = 
		DummyArea.nOffsetY = SHRT_MAX;

		while ( iPos < nAreasMax )
		{
			*pAreaDst++ = DummyArea;
			iPos++;
		}
	}

}

/*
template <class T>
	void EditArea( T *pPic, int iPanel, int iSide )
{

	m_pInclusionDlg->m_picExclusion.SetExclusionAreasFrom( &m_ExclusionAreas[ iPanel ][ iSide ] );	// set area information from preview thumb

	m_pModalPic = pPic;
	m_iModalPanel = iPanel;
	m_iModalSide = iSide;

	if ( m_pInclusionDlg->DoModal() == IDOK )
	{
		m_pInclusionDlg->m_picExclusion.GetExclusionAreasTo( &m_ExclusionAreas[ iPanel ][ iSide ] );
		pPic->SetExclusionAreasFrom( &m_ExclusionAreas[ iPanel ][ iSide ] );

		pPic->ForceRedraw();
	}
}
*/

// swap width and height
//
// if current orientation is landscape ( X >= Y ),
//   rotate clockwise 90?
// else
//   rotate counter-clockwise 90?
void nsAreaUtils::rotateAllAreas( IN short NewOrientation, OUT PRINTERDEVMODE &DevMode )
{
	bool bToPortrait = NewOrientation == DMORIENT_PORTRAIT;

	SPEC_AREA *pStart, *pEnd;

	pStart = DevMode.KplaneAreas;
	pEnd = pStart + sizeof( DevMode.KplaneAreas ) / sizeof( SPEC_AREA );
	rotateArea(pStart, pEnd, bToPortrait);

	pStart = DevMode.ExclAreas;
	pEnd = pStart + sizeof( DevMode.ExclAreas ) / sizeof( SPEC_AREA );
	rotateArea(pStart, pEnd, bToPortrait);

	pStart = DevMode.UvAreas;
	pEnd = pStart + sizeof( DevMode.UvAreas ) / sizeof( SPEC_AREA );
	rotateArea(pStart, pEnd, bToPortrait);
}

void nsAreaUtils::rotateAreasIfNecessary( OUT PRINTERDEVMODE &DevMode )
{
	bitset<elBits> UISettings( DevMode.UISettings );
	short LastOrientation = UISettings[ elAreaOrientation ] ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
	if ( LastOrientation != DevMode.rasdm.dmOrientation )
	{
		short NewOrientation = DevMode.rasdm.dmOrientation;
		rotateAllAreas( NewOrientation, DevMode );
		UISettings[ elAreaOrientation ] = NewOrientation ==  DMORIENT_LANDSCAPE ? true : false;
		DevMode.UISettings = (BYTE)UISettings.to_ulong();
	}
}
